package com.sunrise.gateway.commons.watermark;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;

/**
 * Created by wangmin on 2018/4/27.
 */
public abstract class WatermarkTextPositionUtils {
    private static Logger logger = LoggerFactory.getLogger(WatermarkTextPositionUtils.class);


    /**
     * 获取字符长度，一个汉字作为 1 个字符, 一个英文字母作为 0.5 个字符
     *
     * @param text
     * @return 字符长度，如：text="中国",返回 2；text="test",返回 2；text="中国ABC",返回 4.
     */
    private static int getTextLength(String text, FontMetrics fontMetrics) {
        char[] charArray = text.toCharArray();
        return fontMetrics.charsWidth(charArray, 0, charArray.length);
    }


    /**
     * 将过长的文字切断换行
     *
     * 打印格式如下:
     * -------------------> X轴
     * |
     * |
     * |
     * |
     * |               AAA
     * |BBBBBBBBBBBBBBBBBB
     * |BBBBBBBBBBBBBBBBBB
     * |            BBBBBB
     * ↓             CCCCC
     * Y轴
     *
     * 其中B为过长被切分为多段的文本
     */
    private static java.util.List<WatermarkParam> cutExceedTextToNextLine(WatermarkUtils.MyImageInfo myImageInfo, FontMetrics fontMetrics, WatermarkParam param) {
        int availSize = myImageInfo.width - param.offsetX;
        java.util.List<WatermarkParam> allParts = new ArrayList<>();

        // 分割文字
        for (int startCharIdx = 0; startCharIdx < param.text.length(); ) {
            int partTextWidth = 0;
            int endCharIdx = startCharIdx;
            for (; endCharIdx < param.text.length(); ++endCharIdx) {
                int charWidth = fontMetrics.charWidth(param.text.charAt(endCharIdx));
                if (partTextWidth + charWidth > availSize) {
                    if (0 == partTextWidth)   // 防止无限循环
                        return allParts;
                    break;
                }
                partTextWidth += charWidth;
            }

            WatermarkParam onePart = new WatermarkParam(param);
            onePart.text = param.text.substring(startCharIdx, endCharIdx);
            onePart.textWidth = partTextWidth;
            allParts.add(onePart);

            // 下一个
            startCharIdx = endCharIdx;
        }

        return allParts;
    }

    /**
     * 将过长的文字切断换行, 并且计算每个文字的坐标
     */
    static java.util.List<WatermarkParam> computeTextPosition(WatermarkUtils.MyImageInfo myImageInfo, Graphics2D g2, java.util.List<WatermarkParam> watermarkParamList) throws Exception {
        // 按照offsetToBottom属性从小到大排列
        Collections.sort(watermarkParamList, WatermarkParamComparatorY.watermarkParamComparatorY);
        // 找到最大的y坐标, 以它为基准, 从下往上打印
        int startY = myImageInfo.height - watermarkParamList.get(0).offsetY;

        java.util.List<WatermarkParam> result = new ArrayList<>();

        outer:
        for (WatermarkParam param : watermarkParamList) {
            g2.setFont(new Font(param.fontName, param.fontStyle, param.fontSize));
            g2.setColor(param.color);
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, param.alpha));

            FontMetrics fontMetrics = g2.getFontMetrics();

            param.textWidth = getTextLength(param.text, fontMetrics);
            int textHeight = fontMetrics.getHeight();

            // offset太大
            if (fontMetrics.charWidth('W')*4 + param.offsetX > myImageInfo.width) {
                logger.info("offsetX too big, text = " + param.text);
                continue;
            }
            // 超过宽度, 分割文字
            else if (param.textWidth + param.offsetX > myImageInfo.width) {
                java.util.List<WatermarkParam> allParts = cutExceedTextToNextLine(myImageInfo, fontMetrics, param);

                // 从后往前加入
                for (int partIdx=allParts.size()-1; partIdx>=0; --partIdx) {
                    WatermarkParam partParam = allParts.get(partIdx);
                    partParam.printY = startY - textHeight;
                    if (partParam.printY < textHeight) // 高度不够, 不再打印
                        break outer;
                    partParam.printX = myImageInfo.width - (partParam.offsetX + partParam.textWidth);
                    result.add(partParam);

                    startY -= (textHeight + textHeight/2);   // 向上移动
                }
            }
            // 没有超过宽度
            else {
                param.printY = startY - textHeight;
                if (param.printY < textHeight) // 高度不够, 不再打印
                    break outer;
                param.printX = myImageInfo.width - (param.offsetX + param.textWidth);
                result.add(param);

                startY -= (textHeight + textHeight/2);   // 向上移动
            }
        }

        return result;
    }
}
